package at.fhj.ase.clientarch.server.db.hibernate.entities;

import java.sql.Timestamp;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import at.fhj.ase.clientarch.common.HardwareData;
import at.fhj.ase.clientarch.common.util.CommonUtil;

/**
 * @author cja, sfe | www.fh-joanneum.at | Client Architectures and Design
 */
@Entity
@Table(name = EntityHardwareData.TABLE_NAME)
public class EntityHardwareData {
  static final String TABLE_NAME = "HARDWAREDATA";

  private long id;
  private double cpu;
  private double ram;
  private Timestamp timestamp;

  /** Default constructor for hibernate */
  @SuppressWarnings("unused")
  private EntityHardwareData() {
  }

  /**
   * There is no timestamp specified, therefore the current system time is taken.
   * 
   * @see EntityHardwareData#EntityHardwareData(double, double, Timestamp)
   */
  public EntityHardwareData(final double cpu, final double ram) {
    this(cpu, ram, new Timestamp(System.currentTimeMillis()));
  }

  /**
   * Convenience constructor calling {@link #EntityHardwareData(double, double, Timestamp)}.
   * 
   * @param hwData the {@link HardwareData} where values like {@link HardwareData#getCpu()} are automatically fetched
   */
  public EntityHardwareData(final HardwareData hwData) {
    this(hwData.getCpu(), hwData.getRam(), hwData.getTimestamp());
  }

  /**
   * Create a new instance of this class.
   * 
   * @param cpu set the cpu data in percentage
   * @param ram set the ram data in percentage
   * @param timestamp the timestamp the data record shall have
   */
  public EntityHardwareData(final double cpu, final double ram, final Timestamp timestamp) {
    setCpu(cpu);
    setRam(ram);
    setTimestamp(timestamp);
  }

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  public Long getId() {
    return id;
  }

  @SuppressWarnings("unused")
  private void setId(Long id) {
    this.id = id;
  }

  /* -----------------
   * Getter and Setter
   * ----------------- */

  @Column(nullable = false, columnDefinition = "timestamp default NOW")
  public Timestamp getTimestamp() {
    return timestamp;
  }

  private void setTimestamp(Timestamp timestamp) {
    CommonUtil.checkNullRefNamed(timestamp, "timestamp");
    this.timestamp = timestamp;
  }

  @Column(nullable = false)
  public double getCpu() {
    return cpu;
  }

  private void setCpu(double cpu) {
    this.cpu = cpu;
  }

  @Column(nullable = false)
  public double getRam() {
    return ram;
  }

  private void setRam(double ram) {
    this.ram = ram;
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = (int) (prime * result + cpu);
    result = (int) (prime * result + ram);
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj)
      return true;
    if (obj == null)
      return false;
    if (getClass() != obj.getClass())
      return false;
    final EntityHardwareData other = (EntityHardwareData) obj;
    if ((Double.compare(cpu, other.cpu) == 0) && (Double.compare(ram, other.ram) == 0))
      return true;

    return true;
  }

  public String toString() {
    return getClass().getSimpleName() + ": id: " + id + ", cpu: " + cpu + ", ram: " + ram + ", timestamp: " + timestamp;
  }
}
